using System.Collections.Generic;
using SpecMaker.Core.Dsl;
using SpecMaker.Core.Interfaces;

namespace SpecMaker.Core
{
    public interface ISpecRunner
    {
        void Execute(string assmloc);
    }

    public class SpecRunner : ISpecRunner
    {
        private readonly IAssemblyTypeLoader _assemblyType;
        private readonly ISpecFinder _finder;
        private readonly IReportFactory _factory;
        private readonly RuleExecutor _executor;

        public SpecRunner(IAssemblyTypeLoader assemblyType, ISpecFinder finder,
            IReportFactory factory, RuleExecutor executor)
        {
            _assemblyType = assemblyType;
            _finder = finder;
            _factory = factory;
            _executor = executor;
        }

        public  void Execute(string assmloc)
        {
            var types= _assemblyType.Get(assmloc);
            
            var containers = _finder.GetImpl(types);
            var specresults = new List<SpecResult>();
            foreach (var container in containers)
            {
                
                var specsfromcontainer = container.RunSpecs();
                foreach (var spec in specsfromcontainer)
                {
                    var rules = _executor.Spec(spec);
                    specresults.Add(SpecResultMap(spec, rules));
                }
               
                
            }
            _factory.FromSpecContainers(specresults.ToArray());

            
        }
        private SpecResult SpecResultMap(Spec spec , IEnumerable<RuleResult> results)
        {
            return new SpecResult(spec.TypeUnderDescription.Name, spec.Description, results);
        }
    }
}